﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
using System.Web;
using System.Xml;

namespace DBA.Common
{
    public class ReflectorHelper
    {
        public static T CreateInstance<T>()
        {
            return Activator.CreateInstance<T>();
        }

        public static Dictionary<string, object> GetKeyValueListFromDataRow(DataRow dr)
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            foreach (DataColumn column in dr.Table.Columns)
            {
                dictionary.Add(column.ColumnName, dr[column]);
            }
            return dictionary;
        }

        public static Dictionary<string, object> GetKeyValueListFromForms()
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            foreach (string str in HttpContext.Current.Request.Form)
            {
                dictionary.Add(str, RequestHelper.Form(str));
            }
            return dictionary;
        }

        public static Dictionary<string, object> GetKeyValueListFromObject(object input)
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            foreach (PropertyInfo info in GetProperties(input))
            {
                dictionary.Add(info.Name, GetValue(input, info.Name));
            }
            return dictionary;
        }

        public static Dictionary<string, object> GetKeyValueListFromQueryStrings()
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            foreach (string str in HttpContext.Current.Request.QueryString)
            {
                dictionary.Add(str, RequestHelper.QueryString(str));
            }
            return dictionary;
        }

        public static Dictionary<string, object> GetKeyValueListFromXml(XmlNode no, Xml.ObjectAttrbuteSaveType saveType)
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            switch (saveType)
            {
                case Xml.ObjectAttrbuteSaveType.Attribute:
                    foreach (XmlAttribute attribute in no.Attributes)
                    {
                        dictionary.Add(attribute.Name, attribute.Value);
                    }
                    return dictionary;

                case Xml.ObjectAttrbuteSaveType.ChildNode:
                    foreach (XmlNode node in no.ChildNodes)
                    {
                        dictionary.Add(node.Name, node.InnerText);
                    }
                    return dictionary;
            }
            return dictionary;
        }

        public static Dictionary<string, object> GetKeyValuListFromCookies(string cookieName, bool encode)
        {
            Dictionary<string, object> dictionary = new Dictionary<string, object>();
            HttpCookie cookie = CookieHelper.GetCookie(cookieName);
            foreach (string str in cookie.Values)
            {
                dictionary.Add(str, encode ? UtilsHelper.Decode(cookie[str]) : cookie[str]);
            }
            return dictionary;
        }

        public static T GetObject<T>(Dictionary<string, object> keyValueList)
        {
            T input = CreateInstance<T>();
            foreach (KeyValuePair<string, object> pair in keyValueList)
            {
                PropertyInfo property = GetProperty(input, pair.Key);
                if (property != null)
                {
                    switch (property.PropertyType.Name.ToLower())
                    {
                        case "byte":
                            property.FastSetValue<T>(input, ConvertHelper.ToByte(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToByte(pair.Value), null);
                            break;

                        case "int16":
                            property.FastSetValue<T>(input,ConvertHelper.ToInt16(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToInt16(pair.Value), null);
                            break;

                        case "int32":
                            property.FastSetValue<T>(input,  ConvertHelper.ToInt32(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToInt32(pair.Value), null);
                            break;

                        case "int64":
                            property.FastSetValue<T>(input,ConvertHelper.ToInt64(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToInt64(pair.Value), null);
                            break;

                        case "single":
                            property.FastSetValue<T>(input,ConvertHelper.ToSingle(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToSingle(pair.Value), null);
                            break;

                        case "double":
                            property.FastSetValue<T>(input,ConvertHelper.ToDouble(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToDouble(pair.Value), null);
                            break;

                        case "datetime":
                            property.FastSetValue<T>(input,ConvertHelper.ToDateTime(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToDateTime(pair.Value), null);
                            break;

                        case "decimal":
                            property.FastSetValue<T>(input,ConvertHelper.ToDecimal(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToDecimal(pair.Value), null);
                            break;

                        case "boolean":
                            property.FastSetValue<T>(input,ConvertHelper.ToBoolean(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToBoolean(pair.Value), null);
                            break;

                        case "guid":
                            property.FastSetValue<T>(input,ConvertHelper.ToGuid(pair.Value));
                            //property.SetValue(input, ConvertHelper.ToGuid(pair.Value), null);
                            break;

                        case "string":
                            property.FastSetValue<T>(input, pair.Value.ToString()); 
                            //property.SetValue(input, pair.Value.ToString(), null);
                            break;
                    }
                }
            }
            return input;
        }

        public static PropertyInfo[] GetProperties(object input)
        {
            return input.GetType().GetProperties();
        }

        public static PropertyInfo GetProperty(object input, string propertyName)
        {
            return input.GetType().GetProperty(propertyName);
        }

        public static object GetValue(object input, string propertyName)
        {
            return GetProperty(input, propertyName).GetValue(input, null);
        }

        public static void SetValue(object input, string propertyName, object value)
        {
            GetProperty(input, propertyName).SetValue(input, value, null);
        }
    }
}

